﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using ASPItalia.ModelVirtualCasting.Web.RiaServices;
using System.ComponentModel;
using ASPItalia.ModelVirtualCasting.Silverlight.Data;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Command;
using System.Collections;
using ASPItalia.ModelVirtualCasting.Silverlight.BackOffice.Views;
using System.Windows.Printing;
using System.Windows.Threading;
using System.Runtime.InteropServices.Automation;
using System.Reflection;
using System.IO;
using Uploader;
using System.Collections.Generic;
using Microsoft.Windows.Data.DomainServices;
using System.ServiceModel.DomainServices.Client;
using System.Collections.Specialized;
using System.Linq;
using System.ComponentModel.DataAnnotations;

namespace ASPItalia.ModelVirtualCasting.Silverlight.BackOffice.ViewModels
{
    public class DomainCollectionViewModel : ViewModelBase
    {
        private DataManager _data;
        private EntityQuery<People> query;
        private EntityList<People> source;
        private DomainCollectionViewLoader<People> loader;
        private DomainCollectionView<People> view;

        public RelayCommand FilterCommand { get; private set; }
        public RelayCommand AddCommand { get; private set; }
        public RelayCommand SaveCommand { get; private set; }
        public RelayCommand DeleteCommand { get; private set; }

        public DomainCollectionViewModel()
        {
            if (DesignerProperties.IsInDesignTool)
            {
            }
            else
            {
                _data = new DataManager();
            }

            this.query = _data.DomainContext.GetPeopleQuery().OrderBy(p => p.LastName);
            this.query.IncludeTotalCount = true;
            this.source = new EntityList<People>(_data.DomainContext.Peoples);
            this.loader = new DomainCollectionViewLoader<People>(this.OnLoad, this.OnLoadCompleted);
            this.view = new DomainCollectionView<People>(loader, source);
            this.view.PageSize = 5;

            FilterCommand = new RelayCommand(() =>
            {
                this.query = _data.DomainContext.GetPeopleQuery().OrderBy(p => p.LastName).Where(b => b.LastName.StartsWith(StringSearch));

                this.view.Refresh();
                this.view.MoveToFirstPage();
            });

            INotifyCollectionChanged notifyingSortDescriptions = (INotifyCollectionChanged)this.People.SortDescriptions;
            notifyingSortDescriptions.CollectionChanged += (sender, e) =>
            {
                this.view.MoveToFirstPage();
            };

            AddCommand = new RelayCommand(() =>
            {
                People p = this.People.AddNew() as People;
                p.LastName = "_LastName";
                p.FirstName = "_FirstName";
                p.Type = "C";
                p.Availability = "1";
                p.EmailAddress = "test@test.net";
                p.Gender = "F";
                p.NickName = "_nickname";
                p.EyesColor = "W";
                p.HairColor = "D";
                p.InsertionDate = DateTime.Now;
                p.BirthDate = DateTime.Now;
            });

            SaveCommand = new RelayCommand(() =>
            {
                Processing = Tuple.Create<bool, string>(true, "salvataggio in corso");
                this.People.ToList<People>().ForEach(uur => (uur as IEditableObject).EndEdit());

                _data.DomainContext.SubmitChanges((op) =>
                {
                    if (op.HasError)
                    {
                        Processing = Tuple.Create<bool, string>(false, "errore");
                        op.MarkErrorAsHandled();

                        string msg = op.Error.Message;
                        var _entitiesInError = op.EntitiesInError;
                        foreach (var item in _entitiesInError)
                        {
                            ICollection<ValidationResult> _errors = item.ValidationErrors;

                            foreach (ValidationResult err in _errors)
                            {
                                msg = String.Format("{0} {1}", msg, err.ErrorMessage);
                            }
                        }
                        ErrorWindow.CreateNew(msg);
                    }
                    else if (!op.IsCanceled)
                    {
                        Processing = Tuple.Create<bool, string>(false, "completato");

                        this.view.CancelNew();
                        this.view.CancelEdit();
                        this.view.Refresh();
                    }
                }, null);
            });

            DeleteCommand = new RelayCommand(() =>
            {
                try
                {
                    this.People.Remove(this.People.CurrentItem);
                }
                catch
                {
                }

                this.People.MoveCurrentToFirst();
            });

            Messenger.Default.Register<MessageType>(this, ManageMessage);
        }

        public DomainCollectionView<People> People
        {
            get
            {
                return this.view;
            }
        }

        Tuple<bool, string> _processing;
        public Tuple<bool, string> Processing
        {
            get { return _processing; }
            set
            {
                _processing = value;
                RaisePropertyChanged("Processing");

                Messenger.Default.Send<Tuple<bool, string>>(value);
            }
        }

        string _stringSearch = string.Empty;
        public string StringSearch
        {
            get { return _stringSearch; }
            set
            {
                _stringSearch = value;
                RaisePropertyChanged("StringSearch");
            }
        }

        private void ManageMessage(MessageType messageType)
        {
            switch (messageType)
            {
                case MessageType.DomainCollectionView:
                    this.People.ToList<People>().ForEach(uur => (uur as IEditableObject).CancelEdit());
                    _data.DomainContext.RejectChanges();

                    this.query = _data.DomainContext.GetPeopleQuery().OrderBy(p => p.LastName);
                    this.view.Refresh();
                    this.view.MoveToFirstPage();
                    break;
            }
        }

        private LoadOperation<People> OnLoad()
        {
            Processing = Tuple.Create<bool, string>(true, "caricamento in corso");

            return this._data.DomainContext.Load(this.query.SortAndPageBy(this.view));
        }
        private void OnLoadCompleted(LoadOperation<People> op)
        {
            if (op.HasError)
            {
                Processing = Tuple.Create<bool, string>(false, "errore");

                op.MarkErrorAsHandled();
                ErrorWindow.CreateNew(op.Error.Message);
            }
            else if (!op.IsCanceled)
            {
                Processing = Tuple.Create<bool, string>(false, "completato");

                this.source.Source = op.Entities;
                if (op.TotalEntityCount != -1)
                {
                    this.People.SetTotalItemCount(op.TotalEntityCount);
                }
            }
        }

    }
}